package movepaint.view;

import java.awt.FlowLayout;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;
import javax.swing.JProgressBar;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.awt.Insets;
import javax.swing.Timer;
import movepaint.GestureRecognition;

/**
 * Cette classe permet de créer un Panel contenant une barre de progression
 *	affichant la memoire utilisée par l'application et permettant de forcer
 *	l'appel au garbage collector.
 *
 *	<br><br>
 *	Son utilisation est simple, il suffit de faire appel au constructeur pour
 *		obtenir un panel contenant:
 *		<ul>
 *			<li>Une barre de progression qui gère automatiquement
 *				la progression de la gestion de la mémoire,</li>
 *			<li>Une icone qui permet de forcer le passage du garbage collector.</li>
 *		</ul>
 *
 * @author Paulino A.
 * @version 1.0
 **/
public class UsedMemoryPanel extends JPanel {
    // Longueur de la frame
    private static final int WIDTH = 130;
    // Largeur de la frame
    private static final int HEIGHT = 20;
    // Temps de raffraichissement de la barre de progression
    private static final int SLEEP_TIME = 500;
    // Tooltip du bouton du garbage
    private static final String TOOLTIP_GARBAGE = "Liberer de la memoire";
    // Nom de l'icone du garbage collector
    private static final String NAME_ICON_GARBAGE = "trash.gif";
    // Objet de gestion de la mémoire
    private MemoryMXBean _memoryBean = null;
    // Barre de progression
    private JProgressBar _progressBar = null;

    // JButton qui represente le garbage collector
    private JButton _garbage = null;

    // Timer qui va mettre à jour la barre de progression
    private Timer timer = null;

    /**
     *	Constructeur du panel d'affichage de la mémoire
     **/
    public UsedMemoryPanel() {
        super();

        // Gestionnaire d'agencement
        setLayout(new FlowLayout());

        // On créer les composants
        createComponents();

        // On place les composants
        placeComponents();

        // Ajout de l'action du garbage
        _garbage.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.gc();
            }
        });

        // On démarre le Timer
        timer.start();
    }

    /**
     *	Cette méthode créer les composants de la fenetre
     */
    private void createComponents() {
        // Instance de l'objet contenant des informations sur la mémoire
        _memoryBean = ManagementFactory.getMemoryMXBean();

        // Instance de la barre de progression
        _progressBar = new JProgressBar((int) _memoryBean.getHeapMemoryUsage().getInit(),
                (int) _memoryBean.getHeapMemoryUsage().getMax());
        _progressBar.setStringPainted(true);
        _progressBar.setPreferredSize(new Dimension(WIDTH, HEIGHT));

        // Instance du bouton permettant de forcer le garbage
        _garbage = new JButton(new ImageIcon(GestureRecognition.PATH_IMG + NAME_ICON_GARBAGE));
        _garbage.setContentAreaFilled(false);
        _garbage.setMargin(new Insets(0, 0, 0, 0));
        _garbage.setToolTipText(TOOLTIP_GARBAGE);

        // Creation du Timer mettant à jour la barre de progression
        timer = createTimer();
    }

    /**
     *	Cette méthode place les composants de la fenetre
     */
    private void placeComponents() {
        add(_progressBar);
        add(_garbage);
    }

    /**
     * Méthode renvoyant un timer prêt à démarrer
     */
    private Timer createTimer() {
        // Création d'une instance de listener associée au timer
        ActionListener action = new ActionListener() {

            // Méthode appelée à chaque tic du timer
            public void actionPerformed(ActionEvent event) {
                // On met à jour la barre de progression
                _progressBar.setString(
                        _memoryBean.getHeapMemoryUsage().getUsed() / 1024 + " Kb of " + _memoryBean.getHeapMemoryUsage().getMax() / 1024 + " Kb");
                _progressBar.setValue((int) _memoryBean.getHeapMemoryUsage().getUsed());
            }
        };

        // Création d'un timer qui génère un tic
        // chaque SLEEP_TIME millième de seconde
        return new Timer(SLEEP_TIME, action);
    }
}

